package com.gcsoftware.web.service;

import com.gcsoftware.utils.log.InvokeLog;
import com.gcsoftware.utils.log.LogUtils;
import com.gcsoftware.web.beans.request.GetAppsReq;
import com.gcsoftware.web.mapper.T_GW_APPSMAPPER;
import com.gcsoftware.web.beans.*;
import com.gcsoftware.utils.GenerateIDs;
import com.gcsoftware.utils.KeysUtils;
import com.gcsoftware.utils.MapUtils;
import com.gcsoftware.utils.SysConst;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLException;
import java.util.List;
import java.util.UUID;

/**
 * Created by qs on 2018/3/14.
 */
@Service
public class T_GW_APPS_SERVICE {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private T_GW_APPSMAPPER mapper ;

    public List<T_GW_APPS> queryProviderList(String c_COMPANY_ID) {
        return mapper.queryForList(null,SysConst.DICT_APP_STATUS_PUBLISH,SysConst.DICT_APP_TYPE_PROVIDER,c_COMPANY_ID);
    }

    public List<T_GW_APPS> queryForList(String c_APP_NAME, String c_APP_STATUS,String c_COMPANY_ID){
        return mapper.queryForList(c_APP_NAME,c_APP_STATUS,null,c_COMPANY_ID);
    }

    public T_GW_APPS getById(String c_APP_ID){
        return mapper.get(c_APP_ID,null,null);
    }
    public int updateStatus(String c_APP_ID, String c_APP_STATUS){
        return mapper.updateAppStatus(c_APP_ID,c_APP_STATUS);
    }

    public List<T_GW_APP_IPS > queryForIpList(String c_APP_ID) {
        return mapper.queryIpsList(c_APP_ID);
    }
    private int maxAppIpId() {
        String id = mapper.getMaxAppIPId();

        if(StringUtils.isNotBlank(id)) {
            return Integer.parseInt(id.replace(GenerateIDs.ID_TYPE_APP_IP_ID,""));
        }
        return 0;
    }

    @Transactional
    @InvokeLog(name = "update app" , description = "修改应用信息" , logType = LogUtils.LOG_TYPE_OPERATE)
    public MapUtils updateApp(GetAppsReq req) {
        return 1 == update(req,req.getIps()) ? MapUtils.ok() : MapUtils.error("修改应用信息失败！");
    }

    public int update(T_GW_APPS appInfo , List<T_GW_APP_IPS> ips) {
        try {
            mapper.updateApps(appInfo);
            mapper.batchDeleteIp(appInfo.getC_APP_ID());
            batchInsertAppIps(appInfo.getC_APP_ID(),ips);
            return 1;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            return 0;
        }
    }

    public int updateAppRole(String c_APP_ID, String c_ROLE_ID) {
        return mapper.updateAppRole(c_APP_ID,c_ROLE_ID);
    }

    @InvokeLog(name = "Change app information" , description = "变更应用信息" , logType = LogUtils.LOG_TYPE_OPERATE)
    @Transactional(rollbackFor={RuntimeException.class, Exception.class,SQLException.class})
    public MapUtils appChanged(T_GW_APPS appInfo, List<T_GW_APP_IPS> ips) {
        appInfo.setC_APP_STATUS(SysConst.DICT_APP_STATUS_PUBLISH);
        return 1 == update(appInfo,ips) ? MapUtils.ok() : MapUtils.error("变更应用信息失败！");
    }

    public T_GW_APPS get(String c_APP_ID , String c_APP_NAME, String c_COMPANY_ID) {
        return mapper.get(c_APP_ID,c_APP_NAME,c_COMPANY_ID);
    }

    public MapUtils appInsert(GetAppsReq req){
        if (null != get(null,req.getC_APP_NAME(),req.getC_COMPANY_ID())){
            return MapUtils.error("已存在同名的应用名称");
        }
        return insertApp(req);
    }

    @Transactional
    @InvokeLog(name = "insert app" , description = "新增应用信息" , logType = LogUtils.LOG_TYPE_OPERATE)
    public MapUtils insertApp(GetAppsReq req) {
        try {
            req.setC_APP_ID(UUID.randomUUID().toString().replaceAll("-",""));
            mapper.insertApps(req);
            batchInsertAppIps(req.getC_APP_ID(),req.getIps());
            return MapUtils.ok();
        } catch (Exception e) {
            logger.error("新增应用信息失败！", e);
            return MapUtils.error("新增应用信息失败！");
        }

    }

    @InvokeLog(name = "delete app" , description = "删除应用信息" , logType = LogUtils.LOG_TYPE_OPERATE)
    public int deleteApp(String c_APP_ID) {
        if (1 == mapper.deleteApps(c_APP_ID)) {
            mapper.batchDeleteIp(c_APP_ID);
            return 1;
        } else{
            return 0;
        }
    }
    private void batchInsertAppIps(String c_APP_ID,List<T_GW_APP_IPS> ips) throws Exception {
        if(CollectionUtils.isNotEmpty(ips)) {
            for (T_GW_APP_IPS ip : ips) {
                if (GenerateIDs.getMaxAppIpId() == 0) {
                    GenerateIDs.setMaxAppIpId(maxAppIpId());
                }
                ip.setC_APP_IP_ID(GenerateIDs.GenerateId(GenerateIDs.ID_TYPE_APP_IP_ID));
                ip.setC_APP_ID(c_APP_ID);
                mapper.addAppIps(ip);
            }
        }
    }

    public MapUtils updateAppPwd(String c_APP_ID) {
        try {
            String pwd = KeysUtils.generatePlaintextKey(16);
            if (StringUtils.isNotBlank(pwd)) {
                mapper.updateAppPwds(c_APP_ID);

                T_GW_APP_PWDS pwdInfo = new T_GW_APP_PWDS();
                pwdInfo.setC_APP_ID(c_APP_ID);
                pwdInfo.setC_PASSWORD(pwd);
                pwdInfo.setC_PWD_STATUS(SysConst.DICT_PWD_STATUS_NORMAL);
                mapper.insertAppPwd(pwdInfo);
            }
            return MapUtils.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return MapUtils.error("重置密码失败！");
        }
    }

    public MapUtils updateAppStatus(String c_APP_ID, String c_APP_STATUS) {
        return  1 == mapper.updateAppStatus(c_APP_ID, c_APP_STATUS) ? MapUtils.ok() : MapUtils.error("失败");
    }

}
